﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Storage;

namespace SharPy.Parser
{
    /// <summary>
    /// This class is used to hold essential game info
    /// </summary>
    static class clText
    {
        public static bool IsInitialized = false;

        public static StorageFolder gameFolder;

        private static List<clTextLine> objLine = new List<clTextLine>();

        public static int gameState;

        //Getting text from file
        public async static Task<List<clTextLine>> getText(StorageFile pFile)
        {
            List<clTextLine> toReturn = new List<clTextLine>();

            string fileContent = await FileIO.ReadTextAsync(pFile);
            char[] separator = { '\n' };
            string[] sText = fileContent.Split(separator, StringSplitOptions.RemoveEmptyEntries);
            int lineNo = 0;
            int blockNo = 0;

            int countTabs = 0;
            int countPrevTabs = 0;

            foreach (string s in sText)
            {
                //Count tabs
                countTabs = 0;
                foreach (char c in s)
                {
                    if (c == ' ' || c == '\t')
                    {
                        countTabs++;
                    }
                    else
                        break;
                }

                //Is this the same block?
                if (countTabs != countPrevTabs)
                { blockNo++; }
                countPrevTabs = countTabs;

                //Adding line to static class
                toReturn.Add(new clTextLine(lineNo, s.Trim(), blockNo, countTabs));
                lineNo++;
            }

            //In case not all empty lines were removed
            toReturn.RemoveAll(l => l.sLine.Trim().Length == 0);
            return toReturn;
        }


        public static async Task<int> fillText(StorageFile pFile)
        {
            objLine = await getText(pFile);
            objLine = clParser.lineMerge(objLine);
            IsInitialized = true;
            return 1;
        }

        public static void addLine(int pLineNo, string pLine, int pBlock, int pIndent)
        {
            objLine.Add(new clTextLine(pLineNo
                                        ,pLine
                                        ,pBlock
                                        ,pIndent
                                        ));
        }

        public static string getLine(int pLineNo)
        {
            if (pLineNo < objLine.Count)
                return objLine[pLineNo].sLine;
            else return null;
        }

        /// <summary>
        /// Returns a string array of all text line in the vlock after given line (including line itself).
        /// Blocks are considered to be all lines where indention is more than or equal to that
        /// of given line
        /// </summary>
        public async static Task<clTextLine[]> getBlock(int lineNumber)
        {
            List<clTextLine> block = new List<clTextLine>();
            int index = lineNumber + 1;

            while (objLine[index].nIndention > objLine[lineNumber].nIndention)
            {
                block.Add(objLine[index]);
                index++;
                if (index == objLine.Count - 1)
                    break;
            }

            return block.ToArray();
        }

        internal static int findLabel(string p)
        {
            return objLine.FindIndex(l => System.Text.RegularExpressions.Regex.Replace(l.sLine, @"label\s", "") == p + ":");
        }

        internal static string cleanString(string pString)
        {
            string toReturn = pString.Replace("\\n", Environment.NewLine);
            return toReturn.Replace(@"\", "").Trim('\"');
        }

        internal static void markRead(int p)
        {
            objLine[p].bRead = true;
        }

        internal static List<clTextLine> getHistory()
        {
            return objLine.FindAll(p => p.bRead == true);
        }
    }
   
}
